// import React, { useState, useRef } from 'react';

// interface ImageData {
//     src: string;
//     x: number;
//     y: number;
//     width: number;
//     height: number;
// }

// const DropZone: React.FC = () => {
//     // 存储所有图片的数据
//     const [images, setImages] = useState<ImageData[]>([]);
//     // 跟踪当前选中的图片索引
//     const [selectedImageIndex, setSelectedImageIndex] = useState<number | null>(null);
//     // 存储右键菜单的位置和对应的图片索引
//     const [contextMenu, setContextMenu] = useState<{ top: number; left: number; index: number } | null>(null);
//     // 引用 DropZone 容器元素
//     const dropZoneRef = useRef<HTMLDivElement>(null);
//     // 当用户将图片拖放到 DropZone 时，获取图片的 URL 并将其添加到 images 数组中。同时计算图片的位置，确保它在 DropZone 内部
//     const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
//         // 当用户在浏览器中拖放文件或内容时，默认行为通常是打开文件或链接到某个 URL
//         // 用于阻止这种默认行为，这样我们就可以自定义拖放事件的处理方式
//         e.preventDefault();
//         // e 是一个 React.DragEvent 对象，表示拖放事件
//         // e.dataTransfer 提供了访问与拖放操作相关的数据传输对象的方法。
//         // getData('text') 从 dataTransfer 对象中获取类型为 text 的数据。通常，当用户从文件系统或其他地方拖动图片时，这个数据会包含图片的 URL 或路径
//         const imgSrc = e.dataTransfer.getData('text');
//         // 如果 imgSrc 不为空（即成功获取了图片的 URL），则继续执行后续的操作
//         if (imgSrc) {
//             // dropZoneRef.current?.getBoundingClientRect() 获取 DropZone 容器的边界矩形信息。getBoundingClientRect() 返回一个 DOMRect 对象，其中包含了元素相对于视口的位置和尺寸信息。
//             const dropZoneRect = dropZoneRef.current?.getBoundingClientRect();
//             // e.clientX 和 e.clientY 分别表示鼠标指针在页面中的 X 和 Y 坐标。
//             // dropZoneRect.left 和 dropZoneRect.top 分别表示 DropZone 容器左上角相对于视口的 X 和 Y 坐标。
//             //  newX 计算出图片在 DropZone 内部的 X 坐标。通过 Math.max(0, ...) 确保 X 坐标不会小于 0，通过 Math.min(..., dropZoneRect.width) 确保 X 坐标不会超过 DropZone 的宽度
//             const newX = Math.max(0, Math.min(e.clientX - dropZoneRect.left, dropZoneRect.width));
//             // newY 计算出图片在 DropZone 内部的 Y 坐标。通过 Math.max(0, ...) 确保 Y 坐标不会小于 0，通过 Math.min(..., dropZoneRect.height) 确保 Y 坐标不会超过 DropZone 的高度
//             const newY = Math.max(0, Math.min(e.clientY - dropZoneRect.top, dropZoneRect.height));

//             // setImages 是 React 的 useState Hook 提供的状态更新函数
//             // prevImages 是当前的图片数组。
//             // 在新数组中添加一个新的图片对象，该对象包含：
//             // src: 图片的 URL。
//             // x: 图片在 DropZone 中的 X 坐标。
//             // y: 图片在 DropZone 中的 Y 坐标。
//             // width: 图片的宽度，这里设置为 100 像素。
//             // height: 图片的高度，这里设置为 100 像素。
//             setImages((prevImages) => [
//                 ...prevImages,
//                 { src: imgSrc, x: newX, y: newY, width: 200, height: 100 },
//             ]);
//         }
//     };

//     // 阻止默认的拖动行为，允许用户在 DropZone 上进行拖放操作。
//     const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
//         e.preventDefault();
//     };

//     // 当用户右键点击图片时，设置
//     const handleRightClick = (index: number, e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
//         e.preventDefault(); // 阻止默认的右键菜单
//         setSelectedImageIndex(index);// 设置当前选中的图片索引
//         // e.clientY 和 e.clientX 分别表示鼠标事件发生时相对于浏览器窗口的垂直和水平坐标。当用户在图片上进行右键点击时，这些坐标值会被用来确定上下文菜单应该显示的位置。
//         // 是当前被右键点击的图片在 images 数组中的索引。这个索引是重要的，因为它允许我们在用户选择上下文菜单项（例如“删除”）时，能够准确地知道哪张图片需要被操作。
//         setContextMenu({ top: e.clientY, left: e.clientX, index });
//     };

//     const handleMouseDown = (index: number, e: React.MouseEvent<HTMLImageElement, MouseEvent>) => {
//         e.preventDefault();
//         // 更新状态，将当前图片设为选中状态。
//         setSelectedImageIndex(index);
//         // 计算鼠标点击位置相对于图片左上角的水平偏移量。
//         const startX = e.clientX - images[index].x;
//         // 计算鼠标点击位置相对于图片左上角的垂直偏移量。
//         const startY = e.clientY - images[index].y;

//         // 当鼠标移动时会被调用
//         const onMouseMove = (moveE: MouseEvent) => {
//             const dropZoneRect = dropZoneRef.current?.getBoundingClientRect();

//             // 计算新的图片位置 newX 和 newY，确保它们在 DropZone 的边界内
//             const newX = Math.max(0, Math.min(moveE.clientX - startX - dropZoneRect.left, dropZoneRect.width - images[index].width));
//             const newY = Math.max(0, Math.min(moveE.clientY - startY - dropZoneRect.top, dropZoneRect.height - images[index].height));

//             // 更新 images 状态数组，只更改当前图片的位置
//             setImages((prevImages) =>
//                 prevImages.map((img, i) => (i === index ? { ...img, x: newX, y: newY } : img))
//             );
//         };
//         // 当鼠标按键释放时会被调用
//         const onMouseUp = () => {
//             // 移除之前添加的 mousemove 和 mouseup 事件监听器，以停止移动图片和清理内存。
//             document.removeEventListener('mousemove', onMouseMove);
//             document.removeEventListener('mouseup', onMouseUp);
//         };
//         // 在文档级别添加鼠标移动事件监听器，以便在整个页面范围内都能检测到鼠标的移动。
//         document.addEventListener('mousemove', onMouseMove);
//         // 在文档级别添加鼠标释放事件监听器，以便在任何地方释放鼠标按钮时都能结束图片的移动。
//         document.addEventListener('mouseup', onMouseUp);
//     };

//     const handleResizeStart = (index: number, resizeType: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'left' | 'right' | 'top' | 'bottom', e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
//         // 阻止浏览器的默认行为
//         e.preventDefault();
//         // 记录鼠标按下的水平坐标
//         const startX = e.clientX;
//         // 记录鼠标按下的垂直坐标
//         const startY = e.clientY;
//         // 记录图片的初始宽度
//         const startWidth = images[index].width;
//         // 记录图片的初始高度
//         const startHeight = images[index].height;
//         // 获取 DropZone 的边界信息，用于后续计算新尺寸是否超出边界。
//         const dropZoneRect = dropZoneRef.current?.getBoundingClientRect();

//         // 当鼠标移动时会被调用
//         const onResizeMove = (moveE: MouseEvent) => {
//             let newWidth = startWidth;
//             let newHeight = startHeight;

//             // 根据 resizeType 的不同，计算新的宽度和高度
//             switch (resizeType) {
//                 case 'topLeft':
//                     newWidth = startWidth + (startX - moveE.clientX);
//                     newHeight = startHeight + (startY - moveE.clientY);
//                     break;
//                 case 'topRight':
//                     newWidth = startWidth + (moveE.clientX - startX);
//                     newHeight = startHeight + (startY - moveE.clientY);
//                     break;
//                 case 'bottomLeft':
//                     newWidth = startWidth + (startX - moveE.clientX);
//                     newHeight = startHeight + (moveE.clientY - startY);
//                     break;
//                 case 'bottomRight':
//                     newWidth = startWidth + (moveE.clientX - startX);
//                     newHeight = startHeight + (moveE.clientY - startY);
//                     break;
//                 case 'left':
//                     newWidth = startWidth + (startX - moveE.clientX);
//                     break;
//                 case 'right':
//                     newWidth = startWidth + (moveE.clientX - startX);
//                     break;
//                 case 'top':
//                     newHeight = startHeight + (startY - moveE.clientY);
//                     break;
//                 case 'bottom':
//                     newHeight = startHeight + (moveE.clientY - startY);
//                     break;
//             }

//             // 确保新的宽度和高度不超过 DropZone 的边界
//             const maxWidth = dropZoneRect.width - images[index].x;
//             const maxHeight = dropZoneRect.height - images[index].y;

//             // 使用 Math.max(10, ...) 来确保图片最小尺寸为 10px，防止图片变得太小而不可见
//             // 使用 Math.min(..., maxWidth) 和 Math.min(..., maxHeight) 来限制图片的最大尺寸
//             const clampedWidth = Math.max(10, Math.min(newWidth, maxWidth));
//             const clampedHeight = Math.max(10, Math.min(newHeight, maxHeight));

//             // 更新 images 状态数组，只更改当前图片的宽度和高度
//             setImages((prevImages) =>
//                 prevImages.map((img, i) => (i === index ? { ...img, width: clampedWidth, height: clampedHeight } : img))
//             );
//         };

//         // 当鼠标按键释放时会被调用
//         const onResizeEnd = () => {
//             // 移除之前添加的 mousemove 和 mouseup 事件监听器，以停止调整图片大小和清理内存
//             document.removeEventListener('mousemove', onResizeMove);
//             document.removeEventListener('mouseup', onResizeEnd);
//         };

//         document.addEventListener('mousemove', onResizeMove);
//         document.addEventListener('mouseup', onResizeEnd);
//     };

//     // 函数用于处理删除指定索引的图片
//     const handleDeleteImage = (index: number) => {
//         // 使用 setImages 更新 images 状态
//         // prevImages 是当前的 images 数组
//         // filter 方法创建一个新的数组，其中不包含索引为 index 的元素。
//         // (_, i) => i !== index 是过滤函数，_ 表示当前元素（这里不需要使用），i 是当前元素的索引
//         // 如果当前元素的索引 i 不等于 index，则保留该元素；否则，该元素将被过滤掉
//         setImages((prevImages) => prevImages.filter((_, i) => i !== index));
//         // 使用 setContextMenu 更新 contextMenu 状态
//         // 将 contextMenu 设置为 null，以隐藏当前显示的上下文菜单
//         setContextMenu(null);
//     };

//     return (
//         <div
//             // 将 dropZone 元素引用绑定到 dropZoneRef
//             ref={dropZoneRef}
//             style={{
//                 padding: '20px',
//                 width: '80%',
//                 height: '80%',
//                 margin: '5% auto',
//                 position: 'relative',
//                 background: '#fff',
//                 display: 'flex',
//                 flexWrap: 'wrap',
//                 // 子元素之间的间距为 10 像素
//                 gap: '10px',
//                 overflow: 'hidden',
//             }}
//             // 处理文件或元素拖放到 dropZone 上的行为。
//             onDrop={handleDrop}
//             // 处理拖动过程中鼠标经过 dropZone 的行为。
//             onDragOver={handleDragOver}
//         >
//             {images.map((img, index) => (
//                 <div
//                     key={index}
//                     style={{
//                         // 绝对定位，根据 img.x 和 img.y 设置位置。
//                         position: 'absolute',
//                         // 根据图片数据设置左上角的位置。
//                         left: `${img.x}px`,
//                         top: `${img.y}px`,
//                         // 根据图片数据设置宽度和高度。
//                         width: `${img.width}px`,
//                         height: `${img.height}px`,
//                         // 设置鼠标指针为抓取手形
//                         cursor: 'grab',
//                         // 如果当前图片被选中，则添加橙色阴影
//                         boxShadow: selectedImageIndex === index ? '0 0 10px 2px skyblue' : 'none',
//                         display: 'flex',
//                         alignItems: 'center',
//                         justifyContent: 'center',
//                     }}
//                     // 当用户按下鼠标时调用 handleMouseDown 函数，传递当前图片的索引和事件对象
//                     onMouseDown={(e) => handleMouseDown(index, e)}
//                     // 当用户右键点击时调用 handleRightClick 函数，传递当前图片的索引和事件对象
//                     onContextMenu={(e) => handleRightClick(index, e)}
//                 >
//                     <img
//                         src={img.src}
//                         alt=""
//                         style={{
//                             width: '100%',
//                             height: '100%'
//                         }}
//                     />
//                     {/* 等于当前图片的索引时，显示调整大小的手柄。 */}
//                     {selectedImageIndex === index && (
//                         <>
//                             {/* Top Left */}
//                             <div
//                                 style={{
//                                     position: 'absolute',
//                                     top: '-5px',
//                                     left: '-5px',
//                                     width: '5px',
//                                     height: '5px',
//                                     backgroundColor: 'skyblue',
//                                     cursor: 'nwse-resize',
//                                     borderRadius: '25px'
//                                 }}
//                                 // 事件处理函数 handleResizeStart 会根据不同的手柄类型调用相应的调整逻辑。
//                                 onMouseDown={(e) => handleResizeStart(index, 'topLeft', e)}
//                             />
//                             {/* Top Right */}
//                             <div
//                                 style={{
//                                     position: 'absolute',
//                                     top: '-5px',
//                                     right: '-5px',
//                                     width: '5px',
//                                     height: '5px',
//                                     backgroundColor: 'skyblue',
//                                     cursor: 'nesw-resize',
//                                     borderRadius: '25px'
//                                 }}
//                                 onMouseDown={(e) => handleResizeStart(index, 'topRight', e)}
//                             />
//                             {/* Bottom Left */}
//                             <div
//                                 style={{
//                                     position: 'absolute',
//                                     bottom: '-5px',
//                                     left: '-5px',
//                                     width: '5px',
//                                     height: '5px',
//                                     backgroundColor: 'skyblue',
//                                     cursor: 'nesw-resize',
//                                     borderRadius: '25px'
//                                 }}
//                                 onMouseDown={(e) => handleResizeStart(index, 'bottomLeft', e)}
//                             />
//                             {/* Bottom Right */}
//                             <div
//                                 style={{
//                                     position: 'absolute',
//                                     bottom: '-5px',
//                                     right: '-5px',
//                                     width: '5px',
//                                     height: '5px',
//                                     backgroundColor: 'skyblue',
//                                     cursor: 'nwse-resize',
//                                     borderRadius: '25px'
//                                 }}
//                                 onMouseDown={(e) => handleResizeStart(index, 'bottomRight', e)}
//                             />
//                             {/* Left */}
//                             <div
//                                 style={{
//                                     position: 'absolute',
//                                     top: '50%',
//                                     left: '-5px',
//                                     transform: 'translateY(-50%)',
//                                     width: '5px',
//                                     height: '5px',
//                                     backgroundColor: 'skyblue',
//                                     cursor: 'ew-resize',
//                                     borderRadius: '25px'
//                                 }}
//                                 onMouseDown={(e) => handleResizeStart(index, 'left', e)}
//                             />
//                             {/* Right */}
//                             <div
//                                 style={{
//                                     position: 'absolute',
//                                     top: '50%',
//                                     right: '-5px',
//                                     transform: 'translateY(-50%)',
//                                     width: '5px',
//                                     height: '5px',
//                                     backgroundColor: 'skyblue',
//                                     cursor: 'ew-resize',
//                                     borderRadius: '25px'
//                                 }}
//                                 onMouseDown={(e) => handleResizeStart(index, 'right', e)}
//                             />
//                             {/* Top */}
//                             <div
//                                 style={{
//                                     position: 'absolute',
//                                     top: '-5px',
//                                     left: '50%',
//                                     transform: 'translateX(-50%)',
//                                     width: '5px',
//                                     height: '5px',
//                                     backgroundColor: 'skyblue',
//                                     cursor: 'ns-resize',
//                                     borderRadius: '25px'
//                                 }}
//                                 onMouseDown={(e) => handleResizeStart(index, 'top', e)}
//                             />
//                             {/* Bottom */}
//                             <div
//                                 style={{
//                                     position: 'absolute',
//                                     bottom: '-5px',
//                                     left: '50%',
//                                     transform: 'translateX(-50%)',
//                                     width: '5px',
//                                     height: '5px',
//                                     backgroundColor: 'skyblue',
//                                     cursor: 'ns-resize',
//                                     borderRadius: '25px'
//                                 }}
//                                 onMouseDown={(e) => handleResizeStart(index, 'bottom', e)}
//                             />
//                         </>
//                     )}
//                 </div>
//             ))}
//             {/* 如果 contextMenu 存在（即不为 null），则渲染上下文菜单。 */}
//             {contextMenu && (
//                 <div
//                     style={{
//                         position: 'fixed',
//                         // 根据 contextMenu 中的位置信息设置菜单的位置。
//                         top: contextMenu.top,
//                         left: contextMenu.left,
//                         backgroundColor: 'transparent',
//                         zIndex: 9999,
//                         padding: '5px',
//                     }}
//                 >
//                     {/* 按钮用于删除图片，点击时调用 handleDeleteImage 函数，传递当前图片的索引。 */}
//                     <button onClick={() => handleDeleteImage(contextMenu.index)} style={{
//                         backgroundColor: 'orange',
//                         color: 'white',
//                         padding: '5px 10px',
//                         border: 'none',
//                         borderRadius: '5px',
//                     }}>删除</button>
//                 </div>
//             )}
//         </div>
//     );
// };

// export default DropZone;


import React, { useState, useRef, useEffect } from 'react';

interface ImageData {
  src: string;
  x: number;
  y: number;
  width: number;
  height: number;
}

const DropZone: React.FC = () => {
  const [images, setImages] = useState<ImageData[]>([]);
  const [selectedImageIndex, setSelectedImageIndex] = useState<number | null>(null);
  const [cropRect, setCropRect] = useState<{ x: number; y: number; width: number; height: number } | null>(null);
  const [isDragging, setIsDragging] = useState(false);
  const [dragStartPos, setDragStartPos] = useState<{ x: number; y: number }>({ x: 0, y: 0 });
  const [contextMenu, setContextMenu] = useState<{ top: number; left: number; index: number } | null>(null);
  const dropZoneRef = useRef<HTMLDivElement>(null);
  const canvasRef = useRef<HTMLCanvasElement>(null);

  const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    const imgSrc = e.dataTransfer.getData('text');
    if (imgSrc) {
      const dropZoneRect = dropZoneRef.current?.getBoundingClientRect();
      const newX = Math.max(0, Math.min(e.clientX - dropZoneRect!.left, dropZoneRect!.width));
      const newY = Math.max(0, Math.min(e.clientY - dropZoneRect!.top, dropZoneRect!.height));
      setImages((prevImages) =>
        prevImages.concat({
          src: imgSrc,
          x: newX,
          y: newY,
          width: 200,
          height: 100,
        })
      );
    }
  };

  const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
  };

  const handleMouseDown = (index: number, e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
    e.preventDefault();
    const { clientX, clientY } = e;
    setDragStartPos({ x: clientX - images[index].x, y: clientY - images[index].y });
    setSelectedImageIndex(index);
    setIsDragging(true);
  };

  const handleMouseMove = (e: React.MouseEvent) => {
    if (!isDragging) return;
    const { clientX, clientY } = e;
    const dropZoneRect = dropZoneRef.current?.getBoundingClientRect();
    if (dropZoneRect) {
      setImages((prevImages) => {
        return prevImages.map((img, idx) => {
          if (idx === selectedImageIndex) {
            let newX = Math.min(Math.max(clientX - dragStartPos.x, 0), dropZoneRect.width - img.width);
            let newY = Math.min(Math.max(clientY - dragStartPos.y, 0), dropZoneRect.height - img.height);
            return { ...img, x: newX, y: newY };
          }
          return img;
        });
      });
    }
  };

  const handleMouseUp = () => {
    setIsDragging(false);
  };

  const handleResizeStart = (index: number, direction: string, e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
    e.preventDefault();
    const startX = e.clientX;
    const startY = e.clientY;
    const startWidth = images[index].width;
    const startHeight = images[index].height;
    const startXPercentage = (startX - images[index].x) / startWidth;
    const startYPercentage = (startY - images[index].y) / startHeight;

    const resize = (moveE: MouseEvent) => {
      let newWidth = startWidth;
      let newHeight = startHeight;
      switch (direction) {
        case 'topLeft':
          newWidth = Math.max(10, startWidth - (startX - moveE.clientX));
          newHeight = Math.max(10, startHeight - (startY - moveE.clientY));
          break;
        case 'topRight':
          newWidth = Math.max(10, startWidth + (moveE.clientX - startX));
          newHeight = Math.max(10, startHeight - (startY - moveE.clientY));
          break;
        case 'bottomLeft':
          newWidth = Math.max(10, startWidth - (startX - moveE.clientX));
          newHeight = Math.max(10, startHeight + (moveE.clientY - startY));
          break;
        case 'bottomRight':
          newWidth = Math.max(10, startWidth + (moveE.clientX - startX));
          newHeight = Math.max(10, startHeight + (moveE.clientY - startY));
          break;
        case 'top':
          newHeight = Math.max(10, startHeight - (startY - moveE.clientY));
          break;
        case 'right':
          newWidth = Math.max(10, startWidth + (moveE.clientX - startX));
          break;
        case 'left':
          newWidth = Math.max(10, startWidth - (startX - moveE.clientX));
          break;
        case 'bottom':
          newHeight = Math.max(10, startHeight + (moveE.clientY - startY));
          break;
        default:
          break;
      }

      // 检查新的宽度和高度是否超出容器边界
      newWidth = Math.min(newWidth, dropZoneRef.current?.clientWidth! - images[index].x || Infinity);
      newHeight = Math.min(newHeight, dropZoneRef.current?.clientHeight! - images[index].y || Infinity);

      setImages((prevImages) =>
        prevImages.map((img, i) => (i === index ? { ...img, width: newWidth, height: newHeight } : img))
      );
    };

    const endResize = () => {
      document.removeEventListener('mousemove', resize);
      document.removeEventListener('mouseup', endResize);
    };

    document.addEventListener('mousemove', resize);
    document.addEventListener('mouseup', endResize);
  };

  const handleCropStart = (index: number, e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
    e.preventDefault();
    const cropX = e.clientX - images[index].x;
    const cropY = e.clientY - images[index].y;
    setCropRect({ x: cropX, y: cropY, width: 0, height: 0 });
    const onMouseMove = (moveE: MouseEvent) => {
      const cropWidth = Math.abs(moveE.clientX - cropX);
      const cropHeight = Math.abs(moveE.clientY - cropY);
      setCropRect({ x: cropX, y: cropY, width: cropWidth, height: cropHeight });
    };
    const onMouseUp = () => {
      document.removeEventListener('mousemove', onMouseMove);
      document.removeEventListener('mouseup', onMouseUp);
      applyCrop(index);
    };
    document.addEventListener('mousemove', onMouseMove);
    document.addEventListener('mouseup', onMouseUp);
  };

  const applyCrop = (index: number) => {
    if (canvasRef.current && cropRect) {
      const img = new Image();
      img.src = images[index].src;
      img.onload = () => {
        const canvas = canvasRef.current;
        const ctx = canvas.getContext('2d')!;
        canvas.width = cropRect.width;
        canvas.height = cropRect.height;
        ctx.drawImage(img, cropRect.x, cropRect.y, cropRect.width, cropRect.height, 0, 0, cropRect.width, cropRect.height);
        const croppedBlob = new Blob([canvas.toDataURL()], { type: 'image/png' });
        const croppedUrl = URL.createObjectURL(croppedBlob);
        setImages((prevImages) =>
          prevImages.map((img, i) => (i === index ? { ...img, src: croppedUrl, width: cropRect.width, height: cropRect.height } : img))
        );
        setCropRect(null);
      };
    }
  };

  const handleRightClick = (index: number, e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
    e.preventDefault();
    setContextMenu({ top: e.clientY, left: e.clientX, index });
  };

  const handleDeleteImage = (index: number) => {
    setImages(images.filter((_, i) => i !== index));
    setContextMenu(null);
  };

  useEffect(() => {
    const cleanup = () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    };

    if (isDragging) {
      document.addEventListener('mousemove', handleMouseMove);
      document.addEventListener('mouseup', handleMouseUp);
    }

    return cleanup;
  }, [isDragging]);

  return (
    <div
      ref={dropZoneRef}
      style={{
        overflow: 'hidden',
        padding: '20px',
        width: '80%',
        height: '80%',
        margin: '5% auto',
        position: 'relative',
        background: '#fff',
        display: 'flex',
        flexWrap: 'wrap',
        gap: '10px',
      }}
      onDrop={handleDrop}
      onDragOver={handleDragOver}
    >
      {images.map((img, index) => (
        <div
          key={index}
          style={{
            position: 'absolute',
            left: `${img.x}px`,
            top: `${img.y}px`,
            width: `${img.width}px`,
            height: `${img.height}px`,
            cursor: selectedImageIndex === index ? 'grabbing' : 'grab',
            boxShadow: selectedImageIndex === index ? '0 0 10px 2px skyblue' : 'none',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
          }}
          onMouseDown={(e) => handleMouseDown(index, e)}
          onContextMenu={(e) => handleRightClick(index, e)}
        >
          <img
            src={img.src}
            alt=""
            style={{
              width: '100%',
              height: '100%',
            }}
          />
          {selectedImageIndex === index && (
            <>
              {/* Top Left */}
              <div
                style={{
                  position: 'absolute',
                  top: '-5px',
                  left: '-5px',
                  width: '5px',
                  height: '5px',
                  backgroundColor: 'skyblue',
                  cursor: 'nwse-resize',
                  borderRadius: '25px'
                }}
                onMouseDown={(e) => handleResizeStart(index, 'topLeft', e)}
              />
              {/* Top Right */}
              <div
                style={{
                  position: 'absolute',
                  top: '-5px',
                  right: '-5px',
                  width: '5px',
                  height: '5px',
                  backgroundColor: 'skyblue',
                  cursor: 'nesw-resize',
                  borderRadius: '25px'
                }}
                onMouseDown={(e) => handleResizeStart(index, 'topRight', e)}
              />
              {/* Bottom Left */}
              <div
                style={{
                  position: 'absolute',
                  bottom: '-5px',
                  left: '-5px',
                  width: '5px',
                  height: '5px',
                  backgroundColor: 'skyblue',
                  cursor: 'nesw-resize',
                  borderRadius: '25px'
                }}
                onMouseDown={(e) => handleResizeStart(index, 'bottomLeft', e)}
              />
              {/* Bottom Right */}
              <div
                style={{
                  position: 'absolute',
                  bottom: '-5px',
                  right: '-5px',
                  width: '5px',
                  height: '5px',
                  backgroundColor: 'skyblue',
                  cursor: 'nwse-resize',
                  borderRadius: '25px'
                }}
                onMouseDown={(e) => handleResizeStart(index, 'bottomRight', e)}
              />
              {/* Left */}
              <div
                style={{
                  position: 'absolute',
                  top: '50%',
                  left: '-5px',
                  transform: 'translateY(-50%)',
                  width: '5px',
                  height: '5px',
                  backgroundColor: 'skyblue',
                  cursor: 'ew-resize',
                  borderRadius: '25px'
                }}
                onMouseDown={(e) => handleResizeStart(index, 'left', e)}
              />
              {/* Right */}
              <div
                style={{
                  position: 'absolute',
                  top: '50%',
                  right: '-5px',
                  transform: 'translateY(-50%)',
                  width: '5px',
                  height: '5px',
                  backgroundColor: 'skyblue',
                  cursor: 'ew-resize',
                  borderRadius: '25px'
                }}
                onMouseDown={(e) => handleResizeStart(index, 'right', e)}
              />
              {/* Top */}
              <div
                style={{
                  position: 'absolute',
                  top: '-5px',
                  left: '50%',
                  transform: 'translateX(-50%)',
                  width: '5px',
                  height: '5px',
                  backgroundColor: 'skyblue',
                  cursor: 'ns-resize',
                  borderRadius: '25px'
                }}
                onMouseDown={(e) => handleResizeStart(index, 'top', e)}
              />
              {/* Bottom */}
              <div
                style={{
                  position: 'absolute',
                  bottom: '-5px',
                  left: '50%',
                  transform: 'translateX(-50%)',
                  width: '5px',
                  height: '5px',
                  backgroundColor: 'skyblue',
                  cursor: 'ns-resize',
                  borderRadius: '25px'
                }}
                onMouseDown={(e) => handleResizeStart(index, 'bottom', e)}
              />
              {cropRect && (
                <div
                  style={{
                    position: 'absolute',
                    top: `${cropRect.y}px`,
                    left: `${cropRect.x}px`,
                    width: `${cropRect.width}px`,
                    height: `${cropRect.height}px`,
                    border: '2px dashed red',
                    zIndex: 10,
                  }}
                  onMouseUp={() => applyCrop(selectedImageIndex)}
                />
              )}
            </>
          )}
        </div>
      ))}
      {contextMenu && (
        <div
          style={{
            position: 'fixed',
            top: contextMenu.top,
            left: contextMenu.left,
            backgroundColor: 'transparent',
            zIndex: 9999,
            padding: '5px',
          }}
        >
          <button onClick={() => handleDeleteImage(contextMenu.index)} style={{
            backgroundColor: 'orange',
            color: 'white',
            padding: '5px 10px',
            border: 'none',
            borderRadius: '5px',
          }}>删除</button>
        </div>
      )}
      <canvas ref={canvasRef} style={{ display: 'none' }}></canvas>
    </div>
  );
};

export default DropZone;